<script setup lang="ts">
import type { UploadProps } from 'element-plus'
import { useFFmpeg } from '@/composables/ffmpeg'
import { vi } from 'element-plus/es/locales.mjs'
defineOptions({
  name: 'ffmpeg'
})
const { onInit, ffmpegHandle } = useFFmpeg()
const videoTemplate = useTemplateRef('videoTemplate')
const startTimeRef = ref(0)
const endTimeRef = ref(0)
const fileListRef = ref([])
const loadingRef = ref(true)
const onBeforeUpload: UploadProps['beforeUpload'] = (file: File) => {
  // 文件大小不能超过1024MB
  const is_lt_size = file.size / 1024 / 1024 < 1024
  if (!is_lt_size) {
    alert(`文件大小不能超过${1024}MB`)
  }
  // 文件太大处理很慢
  if (is_lt_size) {
    // 处理视频文件
    videoTemplate.value && (videoTemplate.value.src = URL.createObjectURL(file))
  }
  return false
}
const onVideoEvent = () => {
  if (videoTemplate.value) {
    videoTemplate.value.addEventListener('loadeddata', () => {
      const duration = videoTemplate.value?.duration || 0
      endTimeRef.value = duration
    })
  }
}

const onExportVideo = () => {
  // 导出视频
  const startTime = startTimeRef.value
  const endTime = endTimeRef.value
  if (startTime >= endTime) {
    alert('起始时间必须小于结束时间')
    return
  }
  // 执行ffmpeg命令
  loadingRef.value = true
  ffmpegHandle
    .trimVideo({ videoUrl: videoTemplate.value?.src, startTime, endTime })
    .then((res) => {
      onDownloadDialog(res, 'output.mp4')
    })
    .finally(() => {
      loadingRef.value = false
    })
}
const onExportGif = () => {
  const startTime = startTimeRef.value
  const endTime = endTimeRef.value
  if (startTime >= endTime) {
    alert('起始时间必须小于结束时间')
    return
  }
  // 执行ffmpeg命令
  loadingRef.value = true
  ffmpegHandle
    .handleVideoCommand({
      videoUrl: videoTemplate.value?.src,
      command: ['-ss', String(startTime), '-to', String(endTime), 'output.gif'],
      outputFileName: 'output.gif',
      outputType: 'image/gif'
    })
    .then((res) => {
      onDownloadDialog(res, 'output.gif')
    })
    .finally(() => {
      loadingRef.value = false
    })
}
const onDownloadDialog = (url: string | Blob, saveName: string = '') => {
  // 将 Blob 对象转换为 URL
  if (url instanceof Blob) {
    url = URL.createObjectURL(url) // 创建blob地址
  }

  // 创建下载链接
  const aLink = document.createElement('a')
  aLink.href = url
  aLink.download = saveName

  // 设置链接样式为不影响样式
  aLink.style.display = 'none' // 隐藏链接
  document.body.appendChild(aLink) // 添加到文档中

  // 触发下载
  const event = new MouseEvent('click', {
    bubbles: true,
    cancelable: true,
    view: window
  })
  aLink.dispatchEvent(event)

  // 移除链接
  document.body.removeChild(aLink)

  // 释放 Blob URL
  if ((url as any) instanceof Blob) {
    URL.revokeObjectURL(url)
  }
}
onMounted(() => {
  onInit().finally(() => {
    loadingRef.value = false
  })
  onVideoEvent()
})
</script>
<template>
  <div
    v-loading="loadingRef"
    class="flex flex-col overflow-hidden p-2 text-white bg-gray-700 w-full h-full">
    <div class="text-center">在线视频处理(示例剪切功能,仅供参考,请勿用于商业用途,速度根据电脑性能和文件大小而定)</div>
    <div class="flex-1 overflow-hidden w-full mt-2">
      <video
        ref="videoTemplate"
        class="w-full h-full rounded"
        controls
        crossorigin="anonymous"></video>
    </div>
    <div class="flex items-center justify-center mt-2">
      <el-upload
        v-model:file-list="fileListRef"
        accept="video/*"
        :limit="1"
        class="mr-2"
        :show-file-list="false"
        :before-upload="onBeforeUpload">
        <el-button
          type="primary"
          size="small">
          导入
        </el-button>
      </el-upload>
      <div class="flex items-center mr-2">
        <div>起始时间(秒)</div>
        <el-input-number
          v-model="startTimeRef"
          size="small"
          class="ml-2"></el-input-number>
      </div>
      <div class="flex items-center mr-2">
        <div>结束时间(秒)</div>
        <el-input-number
          v-model="endTimeRef"
          size="small"
          class="ml-2"></el-input-number>
      </div>
      <el-button
        type="primary"
        size="small"
        @click="onExportVideo">
        导出视频
      </el-button>
      <el-button
        type="primary"
        size="small"
        @click="onExportGif">
        导出GIF
      </el-button>
    </div>
  </div>
</template>
<style></style>
